package com.bluefuture.modules.app.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bluefuture.common.exception.GlobalException;
import com.bluefuture.common.utils.HttpClientUtils;
import com.bluefuture.common.utils.PlatformTypeConstant;
import com.bluefuture.common.utils.R;
import com.bluefuture.common.utils.ResultEnum;
import com.bluefuture.modules.app.dao.UserDao;
import com.bluefuture.modules.app.entity.UserEntity;
import com.bluefuture.modules.app.form.LoginForm;
import com.bluefuture.modules.app.form.RegisterForm;
import com.bluefuture.modules.app.form.UpdateForm;
import com.bluefuture.modules.app.form.UserQueryParam;
import com.bluefuture.modules.app.service.CollectUserService;
import com.bluefuture.modules.app.service.UserComplaintService;
import com.bluefuture.modules.app.service.UserService;
import com.bluefuture.modules.app.utils.APPConstant;
import com.bluefuture.modules.app.utils.JwtUtils;
import com.bluefuture.modules.app.vo.UserVO;
import com.bluefuture.modules.sys.security.user.SecurityUser;
import com.bluefuture.modules.sys.service.SysUserTokenService;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static com.bluefuture.modules.app.utils.APPConstant.*;


@Service("userService")
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {

    @Autowired
    private SmsService smsService;
    @Autowired
    private EmailService emailService;
    @Autowired
    private UserComplaintService userComplaintService;
    @Autowired
    private JwtUtils jwtUtils;
    @Autowired
    private SysUserTokenService sysUserTokenService;
    @Value("${spring.profiles.active}")
    private String profile;
    @Autowired
    @Lazy
    private PasswordEncoder passwordEncoder;
    @Autowired
    private CollectUserService collectUserService;
    private static String photoUrlPrefix = "https://api.bluefuturehub.com/blue-future/photo/";

    @Override
    public UserEntity queryByMobile(String mobile) {
        return baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("mobile", mobile));
    }


    @Override
    public UserEntity queryByEmail(String email) {
        return baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("email", email));
    }


    @Override
    public UserVO register(RegisterForm registerForm) {
        Integer registerType = registerForm.getRegisterType();
        if (MOBILE_REGISTER_TYPE.equals(registerType)) {
            //手机注册
            UserEntity userEntity = queryByMobile(registerForm.getMobile());

            if (Objects.nonNull(userEntity)) {
                log.error("【手机号已注册】{}", registerForm.getMobile());
                throw new GlobalException(ResultEnum.MOBILE_ALREADY_REGISTERED_ERROR);
            }
//            if (!"dev".equals(profile)) {
            smsService.checkVerifyCode(registerForm.getMobile(), registerForm.getVerifyCode());
//            }
            userEntity = new UserEntity();
            if (StringUtils.isBlank(registerForm.getName())){
                userEntity.setUsername(registerForm.getMobile());
            }else{
                userEntity.setUsername(registerForm.getName());
            }
            userEntity.setMobile(registerForm.getMobile());
            userEntity.setPassword(passwordEncoder.encode(registerForm.getPassword()));
            userEntity.setCreateTime(new Date());
            userEntity.setUpdateTime(new Date());
            userEntity.setType(registerForm.getType());
            userEntity.setMembershipType(NORMAL_USER);
            if (StringUtils.isNotBlank(registerForm.getPhoto())){
                userEntity.setPhoto(registerForm.getPhoto());
            }else {
                userEntity.setPhoto(photoUrlPrefix + "boy" + (new Random().nextInt(2) + 1) + ".png");
            }
            save(userEntity);
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(userEntity, userVO);
            //生成token
//            String token = jwtUtils.generateToken(userEntity.getUserId());
//            userVO.setToken(token);
            R token = sysUserTokenService.createToken(PlatformTypeConstant.PC, userEntity.getUserId(), userEntity.getUsername());
            userVO.setToken(token.get("token").toString());

            try {
                String userId = getIMUserId(userEntity.getUserId());
                userEntity.setHxId(userId);
                userVO.setHxId(userId);
            } catch (Exception e) {
                e.printStackTrace();
                log.error("调用环信注册用户失败，{}", e.getMessage());
            }
            return userVO;
        } else if (EMAIL_REGISTER_TYPE.equals(registerType)) {
            //邮箱注册
            UserEntity userEntity = queryByEmail(registerForm.getEmail());
            if (Objects.nonNull(userEntity)) {
                log.error("【邮箱已注册】{}", registerForm.getEmail());
                throw new GlobalException(ResultEnum.EMAIL_ALREADY_REGISTERED_ERROR);
            }
//            if (!"dev".equals(profile)) {
            emailService.checkVerifyCode(registerForm.getEmail(), registerForm.getVerifyCode());
//            }
            userEntity = new UserEntity();
            if (StringUtils.isBlank(registerForm.getName())){
                userEntity.setUsername(registerForm.getEmail());
            }else{
                userEntity.setUsername(registerForm.getName());
            }
            userEntity.setEmail(registerForm.getEmail());
            userEntity.setPassword(passwordEncoder.encode(registerForm.getPassword()));
            userEntity.setCreateTime(new Date());
            userEntity.setType(registerForm.getType());
            userEntity.setMembershipType(NORMAL_USER);
            if (StringUtils.isNotBlank(registerForm.getPhoto())){
                userEntity.setPhoto(registerForm.getPhoto());
            }else {
                userEntity.setPhoto(photoUrlPrefix + "boy" + (new Random().nextInt(2) + 1) + ".png");
            }
            save(userEntity);
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(userEntity, userVO);
            //生成token
//            String token = jwtUtils.generateToken(userEntity.getUserId());
//            userVO.setToken(token);
            R token = sysUserTokenService.createToken(PlatformTypeConstant.PC, userEntity.getUserId(), userEntity.getUsername());
            userVO.setToken(token.get("token").toString());

            try {
                String userId = getIMUserId(userEntity.getUserId());
                userEntity.setHxId(userId);
                userVO.setHxId(userId);
                updateById(userEntity);
            } catch (Exception e) {
                e.printStackTrace();
                log.error("调用环信注册用户失败，{}", e.getMessage());
            }

            return userVO;
        } else {
            throw new GlobalException(ResultEnum.PARAM_ERROR.getCode(), "请选择注册方式");
        }
    }

    private String getIMUserId(Long userId) {
        String stockInfo = "";
        try {
            JSONObject json = new JSONObject();
            json.put("username", "huber" + userId);
            json.put("password", "huber" + userId);
            String url = "https://s-1-3-s-api.maximtop.cn/user/register/v2";
            String headerName = "app_id";
            String headerValue = "dwcfnxtehayy";
            stockInfo = HttpClientUtils.httpPost(url, JSON.toJSONString(json), headerName, headerValue);
            System.out.println(stockInfo);
        } catch (Exception e) {
            log.error("【聊天注册接口接口调用失败】，失败原因：{}", e.getMessage());
            throw e;
        }


        log.info("聊天注册接口接口查询响应数据:" + stockInfo);
        JSONObject jsonObject = JSON.parseObject(stockInfo);
        if (Objects.isNull(jsonObject)) {
            throw new GlobalException("聊天注册接口接口查询响应数据为空");
        }
        String code = jsonObject.getString("code");
        //查询成功
        if (Objects.nonNull(code) && "200".equals(code)) {
            JSONObject content = jsonObject.getJSONObject("data");
            if (Objects.nonNull(content)) {
                String iMuserId = content.getString("user_id");
                if (Objects.nonNull(iMuserId)) {
                    return iMuserId;
                }
                throw new GlobalException("聊天注册接口接口查询响应user_id数据为空");
            } else {
                throw new GlobalException("聊天注册接口接口查询响应data数据为空");
            }
        }
        throw new GlobalException("聊天注册接口接口查询响应数据状态码为" + code);
    }

    @Override
    public UserVO login(LoginForm form) {
        UserEntity user = queryByMobile(form.getUser());
        if (Objects.isNull(user)) {
            user = queryByEmail(form.getUser());
        }

        if (Objects.isNull(user)) {
            throw new GlobalException(ResultEnum.PARAM_ERROR.getCode(), "账号或密码错误");
        }

        //密码错误
        if (!passwordEncoder.matches(form.getPassword(), user.getPassword())) {
            throw new GlobalException(ResultEnum.PARAM_ERROR.getCode(), "账号或密码错误");
        }
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        //生成token
//            String token = jwtUtils.generateToken(userEntity.getUserId());
//            userVO.setToken(token);
        R token = sysUserTokenService.createToken(PlatformTypeConstant.PC, user.getUserId(), user.getUsername());
        userVO.setToken(token.get("token").toString());

        user.setUpdateTime(new Date());
        updateById(user);
        return userVO;
    }

    @Override
    public UserVO update(UpdateForm form) {
        UserEntity entity = getById(SecurityUser.getUserId());
        if (Objects.isNull(entity)) {
            return null;
        }
        entity.setUsername(form.getName());
        entity.setOtherContact(form.getOtherContact());
        entity.setInfo(form.getInfo());
        entity.setPhoto(form.getPhoto());
        entity.setMobile(form.getMobile());
        entity.setEmail(form.getEmail());
        entity.setBirth(form.getBirth());
        entity.setGender(form.getGender());
//        if (form.getGender() == 1) {
//            entity.setPhoto(photoUrlPrefix + "boy" + (new Random().nextInt(2) + 1) + ".png");
//        } else {
//            entity.setPhoto(photoUrlPrefix + "girl" + (new Random().nextInt(2) + 1) + ".png");
//        }
        entity.setUpdateTime(new Date());
        entity.setCompany(form.getCompany());
        entity.setIndustry(form.getIndustry());
        updateById(entity);
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(userVO, userVO);
        return userVO;
    }

    @Override
    public Page<UserVO> userList(UserQueryParam param) {
        Long userId = SecurityUser.getUserId();
        List<Integer> collectUserIds = collectUserService.listCollectUserIds();
        UserEntity userEntity = getById(userId);
        if (Objects.isNull(userEntity)) {
            return null;
        }
        List<Long> blockUserIds = userComplaintService.getBlockUserIds(userId);
//        if (APPConstant.NORMAL_USER.equals(userEntity.getType())) {
//            param.setPageSize(10);
//            param.setPageNumber(1);
//        }
        Page page = new Page(param.getPageNumber(), param.getPageSize());
        LambdaQueryWrapper<UserEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//        lambdaQueryWrapper.ne(UserEntity::getUserId,userId);
        if (param.getType() != null) {
            lambdaQueryWrapper.eq(UserEntity::getType, param.getType());
        }
        if (StringUtils.isNotBlank(param.getParam())) {
            lambdaQueryWrapper.and(e -> e.like(UserEntity::getUsername, param.getParam())
                    .or().like(UserEntity::getInfo, param.getParam()));

        }
        lambdaQueryWrapper.notIn(CollectionUtil.isNotEmpty(blockUserIds),UserEntity::getUserId,blockUserIds);
        lambdaQueryWrapper.orderByDesc(UserEntity::getUpdateTime);
        Page<UserEntity> userEntityPage = page(page, lambdaQueryWrapper);
        Page<UserVO> returnPage = new Page<>();
        List<UserEntity> records = userEntityPage.getRecords();
        BeanUtils.copyProperties(userEntityPage, returnPage, "records");
        if (!CollectionUtils.isEmpty(records)) {
            List<UserVO> userVoList = records.stream().map(e -> {
                UserVO userVo = new UserVO();
                BeanUtils.copyProperties(e, userVo);
                boolean contains = collectUserIds.contains(e.getUserId().intValue());
                userVo.setIsCollect(contains);
                return userVo;
            }).collect(Collectors.toList());
            returnPage.setRecords(userVoList);
        }
        return returnPage;
//        Page page = new Page(queryParam.getPageNumber(), queryParam.getPageSize());
//        String param = queryParam.getParam();
//        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//        lambdaQueryWrapper.and(Objects.nonNull(param), e -> e.like(User::getName, param).or().like(User::getMobile, param));
//        lambdaQueryWrapper.eq(User::getType, queryParam.getType())
//                .orderByDesc(User::getCreateTime);
//        IPage<User> userPage = userService.page(page, lambdaQueryWrapper);
//        Page<UserVo> returnPage = new Page<>();
//        List<User> records = userPage.getRecords();
//        BeanUtils.copyProperties(userPage, returnPage, "records");
//        if (!CollectionUtils.isEmpty(records)) {
//            List<UserVo> userVoList = records.stream().map(e -> {
//                UserVo userVo = new UserVo();
//                BeanUtils.copyProperties(e, userVo);
//                return userVo;
//            }).collect(Collectors.toList());
//            returnPage.setRecords(userVoList);
//        }
//        return returnPage;
//        return null;
    }

    @Override
    public List<UserEntity> allUsers() {
        List<UserEntity> list = list();
        return list;
    }

    @Override
    public void forgotPassword(String contact, String newPassword) {
        String EMAIL_REGEX = "^[\\w-_\\.+]*[\\w-_\\.]\\@([\\w]+\\.)+[\\w]+[\\w]$";
        if (contact.matches(EMAIL_REGEX)) {
            QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<>();

            queryWrapper.eq("email", contact);
            UserEntity user = getOne(queryWrapper);
            if (user == null) {
                throw new GlobalException(ResultEnum.USER_NO_REGISTER_ERROR);
            }
            user.setPassword(passwordEncoder.encode(newPassword));
            user.setUpdateTime(new Date());
            updateById(user);
        } else {
            QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<>();

            queryWrapper.eq("mobile", contact);
            UserEntity user = getOne(queryWrapper);
            if (user == null) {
                throw new GlobalException(ResultEnum.USER_NO_REGISTER_ERROR);
            }
            user.setPassword(passwordEncoder.encode(newPassword));
            user.setUpdateTime(new Date());
            updateById(user);
        }

    }

    public static void main(String[] args) {
        ArrayList<Integer> integers = Lists.newArrayList(1, 2, 3);
        ArrayList<Integer> integer1 = Lists.newArrayList(1, 2, 4);
        integer1.removeAll(integers);
        System.out.println(integer1);
//        for (int i = 0; i < 100; i++) {
//            System.out.println(photoUrlPrefix + "boy" + (new Random().nextInt(2) + 1) + ".png");
//        }
//        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
//        boolean matches = bCryptPasswordEncoder.matches("123", "$2a$10$qrEvB/TnOKuMFsrQLc4Wh.McgKaFqlV29ePsv7CBblZeBMPQZM8Xu");
//        System.out.println(matches);
    }

    @Override
    public void updateUserToNormalUser(Long userId) {
        LambdaUpdateWrapper<UserEntity> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(UserEntity::getUserId, userId)
                .set(UserEntity::getUpdateTime, new Date())
                .set(UserEntity::getMembershipType, 1);
        update(wrapper);
    }

    @Override
    public List<UserVO> selectByIds(List<Integer> collectUserIds) {
        if (CollectionUtil.isEmpty(collectUserIds)) {
            return new ArrayList<>();
        }
        List<Long> blockUserIds = userComplaintService.getBlockUserIds(SecurityUser.getUserId());
        if (CollectionUtil.isNotEmpty(blockUserIds)){
            List<Integer> collect = blockUserIds.stream().map(Long::intValue).collect(Collectors.toList());
            collectUserIds.removeAll(collect);
        }
        if (CollectionUtil.isEmpty(collectUserIds)) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<UserEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(UserEntity::getUserId, collectUserIds);
        List<UserEntity> list = list(wrapper);
        List<UserVO> result = list.stream().map(e -> {
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(e, userVO);
            return userVO;
        }).collect(Collectors.toList());
        return result;
    }
}
